package com.azzcs.lifecycle;

import com.azzcs.lifecycle.exception.LifecycleException;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author: wzg
 * @Date: 2021/1/7 下午3:10
 */
public abstract class LifecycleBase implements Lifecycle{

    List<LifecycleListener> listeners = new CopyOnWriteArrayList<>();

    private volatile LifecycleState state = LifecycleState.NEW;
    @Override
    public void addLifecycleListener(LifecycleListener listener) {
        listeners.add(listener);
    }

    @Override
    public List<LifecycleListener> findLifecycleListeners() {
        return listeners;
    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {
        listeners.remove(listener);
    }

    @Override
    public void init() {
        if(LifecycleState.NEW != state){
            throw new LifecycleException();
        }
        setState(LifecycleState.INITIALIZING,null);
        initInternal();
        setState(LifecycleState.INITIALIZED,null);
    }

    protected abstract void initInternal();
    protected abstract void startInternal();

    @Override
    public void start() {
        if(LifecycleState.NEW == state){
            init();
        }
        if(LifecycleState.INITIALIZED != state){
            throw new LifecycleException();
        }
        setState(LifecycleState.STARTING_PREP,null);
        startInternal();
        setState(LifecycleState.STARTED,null);
    }



    @Override
    public void stop() {
        // TODO 暂不实现
    }

    @Override
    public void destroy() {
        // TODO 暂不实现
    }

    @Override
    public LifecycleState getState() {
        return state;
    }

    @Override
    public String getStateName() {
        return state.name();
    }

    /**
     * 设置状态
     * @param state
     * @param data
     */
    protected void setState(LifecycleState state, Object data) {
        this.state = state;
        fireLifecycleEvent(state,data);
    }

    /**
     * 触发事件
     * @param state
     * @param data
     */
    protected void fireLifecycleEvent(LifecycleState state, Object data) {
        for (LifecycleListener listener : listeners) {
            listener.lifecycleEvent(state,data);
        }
    }

}
